package utils

import (
	"fmt"
	"log"
	"os"
	"text/template"
	
	"gorm.io/gorm"
)

// Handler 模板
const handlerTemplate = `package handler_sys

import (
	_ "go_web/internal/model"
	"go_web/internal/model/model_sys"
	"go_web/internal/req/req_sys"
	"go_web/internal/service/service_sys"
	"go_web/pkg/req"
	"go_web/pkg/res"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

type {{.ModelName}}Handler struct {
	{{.ModelName}}Service *service_sys.{{.ModelName}}Service
}

func New{{.ModelName}}Handler({{.ModelName}}Service *service_sys.{{.ModelName}}Service) *{{.ModelName}}Handler {
	return &{{.ModelName}}Handler{ {{.ModelName}}Service }
}

// Detail 查询{{.ModelName}}详情
// @Summary 查询{{.ModelName}}详情
// @Tags {{.ModelName}}Handler
// @Accept json
// @Produce json
// @Param id query string true "主键ID"
// @Success 200 {object} res.R[model_sys.{{.ModelName}}] "{{.ModelName}}"
// @Router /{{.ModelName | ToSnakeCase}}/detail [get]
func (h *{{.ModelName}}Handler) Detail(ctx *gin.Context) {
	id := ctx.Query("id")
	id64, err := strconv.ParseInt(id, 10, 64)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "无效的ID"})
		return
	}
	{{.ModelName}}, err := h.{{.ModelName}}Service.Detail(ctx, id64)
	if err != nil {
		ctx.JSON(http.StatusOK, res.NewR[string]().Fail("查询不到"))
		return
	}
	ctx.JSON(http.StatusOK, res.NewR[model_sys.{{.ModelName}}]().Ok(*{{.ModelName}}))
}

// Page 分页查询{{.ModelName}}
// @Summary 分页查询{{.ModelName}}
// @Tags {{.ModelName}}Handler
// @Accept json
// @Produce json
// @Param queryParams query req_sys.{{.ModelName}}PageReq false "分页请求参数"
// @Success 200 {object} res.R[res.PageRes]
// @Router /{{.ModelName | ToSnakeCase}}/page [get]
func (h *{{.ModelName}}Handler) Page(ctx *gin.Context) {
	var pageReq req_sys.{{.ModelName}}PageReq
	if err := ctx.ShouldBindQuery(&pageReq); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	page, err := h.{{.ModelName}}Service.Page(ctx, pageReq)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, res.NewR[res.PageRes]().Ok(*page))
}

// Add 创建{{.ModelName}}
// @Summary 创建{{.ModelName}}
// @Tags {{.ModelName}}Handler
// @Accept json
// @Produce json
// @Param jsonParams body req_sys.{{.ModelName}}AddReq true "{{.ModelName}}"
// @Success 200 {object} res.R[int64] "操作结果"
// @Router /{{.ModelName | ToSnakeCase}}/add [post]
func (h *{{.ModelName}}Handler) Add(ctx *gin.Context) {
	var reqSys req_sys.{{.ModelName}}AddReq
	if err := ctx.ShouldBindJSON(&reqSys); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	id, err := h.{{.ModelName}}Service.Add(ctx, reqSys)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	ctx.JSON(http.StatusOK, res.NewR[int64]().Ok(id))
}

// Edit 修改{{.ModelName}}
// @Summary 修改{{.ModelName}}
// @Tags {{.ModelName}}Handler
// @Accept json
// @Produce json
// @Param jsonParams body req_sys.{{.ModelName}}EditReq true "{{.ModelName}}"
// @Success 200 {object} res.R[int64] "操作结果"
// @Router /{{.ModelName | ToSnakeCase}}/edit [post]
func (h *{{.ModelName}}Handler) Edit(ctx *gin.Context) {
	var reqSys req_sys.{{.ModelName}}EditReq
	if err := ctx.ShouldBindJSON(&reqSys); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	n, err := h.{{.ModelName}}Service.Edit(ctx, reqSys)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	ctx.JSON(http.StatusOK, res.NewR[int64]().Ok(n))
}

// Delete 删除{{.ModelName}}
// @Summary 删除{{.ModelName}}
// @Tags {{.ModelName}}Handler
// @Accept json
// @Produce json
// @Param jsonParams body req.IdsReq true "ID集合"
// @Success 200 {object} res.R[int64] "操作结果"
// @Router /{{.ModelName | ToSnakeCase}}/delete [post]
func (h *{{.ModelName}}Handler) Delete(ctx *gin.Context) {
	var idsReq req.IdsReq
	if err := ctx.ShouldBindJSON(&idsReq); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	n, err := h.{{.ModelName}}Service.Delete(ctx, idsReq)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	ctx.JSON(http.StatusOK, res.NewR[int64]().Ok(n))
}
`

// 生成 handler 文件并添加日志输出
func GenerateHandler(db *gorm.DB, dbName string, modelName *string) error {
	// 记录生成开始
	log.Printf("开始生成 %s handler...\n", modelName)
	if modelName == nil {
		tableList, err := getTables(db, dbName, nil)
		if err != nil {
			return err
		}
		for i := range tableList {
			tempModelName := toCamelCase(tableList[i].TableName)
			generateHandlerFile(&tempModelName)
		}
	} else {
		generateHandlerFile(modelName)
	}

	return nil
}

func generateHandlerFile(modelName *string) error {
	// 使用模板
	tmpl, err := template.New("handler").Funcs(template.FuncMap{
		"ToSnakeCase": ToSnakeCase, // 使用之前的 ToSnakeCase 函数
	}).Parse(handlerTemplate)
	if err != nil {
		log.Printf("模板解析失败: %v\n", err)
		return err
	}

	// 创建 handler 文件
	fileName := fmt.Sprintf("./dal/handler_sys/%s_handler.go", ToSnakeCase(*modelName))
	file, err := os.Create(fileName)
	if err != nil {
		log.Printf("文件创建失败: %v\n", err)
		return err
	}
	defer file.Close()

	// 执行模板生成
	err = tmpl.Execute(file, map[string]string{
		"ModelName": *modelName,
	})
	if err != nil {
		log.Printf("模板渲染失败: %v\n", err)
		return err
	}

	// 输出生成成功的日志
	log.Printf("成功生成 %s handler 文件: %s\n", *modelName, fileName)
	return nil
}
